package org.hcyspartnoc.demo.common.core.interceptors;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.hcyspartnoc.demo.common.core.annotation.PreAuthorize;
import org.hcyspartnoc.demo.common.core.constant.HttpStatus;
import org.hcyspartnoc.demo.common.core.context.BaseContextHolder;
import org.hcyspartnoc.demo.common.core.enums.CoreSysRole;
import org.hcyspartnoc.demo.common.enums.system.SysPermissionStatusEnum;
import org.hcyspartnoc.demo.common.enums.system.SysUserStatusEnum;
import org.hcyspartnoc.demo.common.exception.framework.AuthException;
import org.hcyspartnoc.demo.common.exception.system.SysUserException;
import org.hcyspartnoc.demo.pojo.po.system.SysUserPo;
import org.hcyspartnoc.demo.utils.RequestUtil;
import org.hcyspartnoc.demo.utils.redis.RedisComponent;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import java.lang.reflect.Method;
import java.util.Objects;

@Component
public class AuthInterceptor implements HandlerInterceptor {
    @Resource
    private RedisComponent redisComponent;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        Integer userId = redisComponent.getUidByToken(RequestUtil.getToken());
        if (Objects.isNull(userId))
            throw AuthException.errorOfTokenExpires();
        SysUserPo sysUserPo = Db.getOne(new LambdaQueryWrapper<>(SysUserPo.class).eq(SysUserPo::getId, userId));
        if (Objects.isNull(sysUserPo))//用户为空
            throw AuthException.errorOfTokenExpires();
        if (!Objects.requireNonNull(SysUserStatusEnum.getByCode(sysUserPo.getStatus()))
                .equals(SysUserStatusEnum.USABLE))
            throw new SysUserException(SysUserException.USER_STATUS_ERROR, HttpStatus.UNAUTHORIZED);
        // 刷新token
        redisComponent.setToken(RequestUtil.getToken(), userId);
        //获取用户对应的角色
        Integer ruRoleId = redisComponent.getRU_RoleId(userId);
        if (Objects.isNull(ruRoleId))
            throw AuthException.errorOfPermissionFailed();
//        //将用户加入上下文
        sysUserPo.setRoleId(ruRoleId);
        BaseContextHolder.getContext().setBaseCurrentUser(sysUserPo);
        //验证角色对应权限
        if (handler instanceof HandlerMethod handlerMethod) {
            Method method = handlerMethod.getMethod();
            if (method.isAnnotationPresent(PreAuthorize.class)) {//如果方法有权限验证注解修饰，则进入验证
                PreAuthorize annotation = method.getAnnotation(PreAuthorize.class);
                if (!ruRoleId.equals(CoreSysRole.SUPER_ADMIN.getId())) {//超级管理员跳过验证
                    // 查询权限是否需要校验
                    SysPermissionStatusEnum permissionStatus = redisComponent.getPermissionStatus(annotation.auth());
                    if (Objects.isNull(permissionStatus))
                        throw AuthException.errorOfPermissionFailed();
                    // 如果权限状态是启用验证
//                    if (permissionStatus.equals(SysPermissionStatusEnum.VERIFY)) {
//                        // 如果角色没有该权限
//                        if (Objects.isNull(redisComponent.getRP_PermissionId(ruRoleId, annotation.auth())))
//                            throw AuthException.errorOfPermissionFailed();
//                    }
                }
            }
        }
        return true;
    }
}
